package com.tx.server;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;

/**
 * @author dengguoxing
 * @date 2019/10/31
 * description
 **/
public class WebSocketServerInitializer extends ChannelInitializer<SocketChannel> {

    private String path;

    private final WebSocketListener webSocketListener;

    /**
     * 读操作空闲
     */
    private final static int READER_IDLE_TIME_SECONDS = 0;

    /**
     * 写操作空闲
     */
    private final static int WRITER_IDLE_TIME_SECONDS = 0;

    /**
     * 读写全部空闲
     */
    private final static int ALL_IDLE_TIME_SECONDS = 60;


    public WebSocketServerInitializer(WebSocketListener webSocketListener, String path) {
        this.webSocketListener = webSocketListener;
        this.path = path;
    }

    /**
     * 入站时，从ChannelPipeline的第一个ChannelInHandler执行到最后一个。
     * 出站时，从ChannelPipeline的最后一个ChannelOutHandler执行到第一个。
     * 在ChannelHandler之间传递的是ChannelHandlerContext，可以看作是ChannelHandler与ChannelPipeline之间的绑定关系。
     * 通过ChannelHandlerContext.channel().writeAndFlush写入消息，是到达ChannelPipeline尾部才写入消息，
     * 而ChannelHandlerContext.writeAndFlush写入消息，是到达下一个ChannelInHandler就写入消息。
     *
     * @param ch
     * @throws Exception
     */
    @Override
    public void initChannel(SocketChannel ch) throws Exception {

        //Outbound的执行顺序为注册顺序的逆序
        ch.pipeline()
                //15秒没有发送消息 将IdleStateHandler 添加到 ChannelPipeline 中
                .addLast("idle", new IdleStateHandler(READER_IDLE_TIME_SECONDS, WRITER_IDLE_TIME_SECONDS, ALL_IDLE_TIME_SECONDS))
                // Http消息编码解码,将请求和应答的消息编码或者解码为HTTP消息
                .addLast("http-codec", new HttpServerCodec())

                // Http消息组装
                .addLast("aggregator", new HttpObjectAggregator(65536))

                // WebSocket通信支持
                .addLast("http-chunked", new ChunkedWriteHandler())

                //自定义的业务处理组件
                .addLast("ws-handler", new CustomWebSocketHandle(webSocketListener, path))

                .addLast(new WebSocketServerHandler());
    }
}

